package com.tanhua.server.service;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.autoconfig.template.SmsTemplate;
import com.tanhua.commons.constant.Constants;
import com.tanhua.commons.exception.TanHuaException;
import com.tanhua.commons.utils.JwtUtils;
import com.tanhua.dubbo.api.db.UserApi;
import com.tanhua.model.db.User;
import com.tanhua.model.vo.ErrorResult;
import lombok.extern.log4j.Log4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Log4j
public class UserService {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private SmsTemplate smsTemplate;

    @DubboReference
    private UserApi userApi;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    /**
     * 发送验证码
     * @param phone
     */
    public void sendCode(String phone) {
        String key = "VALIDATE_CODE_" + phone;
        // 1.根据key查询redis中是否有验证码
        String redisCode = redisTemplate.opsForValue().get(key);

        // 2.如果有值，则表示验证码未失效
        if(!StringUtils.isEmpty(redisCode)){
            throw new TanHuaException(ErrorResult.duplicate());
        }

        // 3.没有值，则生成验证码调用短信平台生成验证码
//        String code = RandomStringUtils.randomNumeric(6);
        String code = "123456";
        smsTemplate.sendSms(phone,code);

        // 4.将验证码存入redis，5分钟有效
//        redisTemplate.opsForValue().set(key,code, Duration.ofMinutes(5));
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);

        log.debug("****手机号：*****"+phone+"***验证码发送成功****验证码：***"+code+"*********");
    }


    /**
     * 登录注册功能实现
     * @param phone
     * @param verificationCode
     * @return
     */
    public Map login(String phone, String verificationCode) {
        // 定义一个旗帜变量，判断是否是新用户
        // false：老用户    true：新用户
        boolean isNew = false;

        // 保证和redis中的key名字一致
        String key = "VALIDATE_CODE_" + phone;

        // 1、根据key查询redis是否有验证码，如果没有值，则表示验证码过期
        String redisInCode = redisTemplate.opsForValue().get(key);
        if(StringUtils.isEmpty(redisInCode)){
            throw new TanHuaException(ErrorResult.loginError());
        }

        // 2、如果有值，将前端传入验证码和redis验证码比较，如果不一样，则表示验证码输入错误
        if(!verificationCode.equals(redisInCode)){
            throw new TanHuaException(ErrorResult.validateCodeError());
        }

        // 3、如果一样，从redis删除验证码，防止重复提交
        redisTemplate.delete(key);

        // 4、根据手机号查询mysql数据库
        User loginUser = userApi.findByMobile(phone);

        // 5、如果用户不存在，自动注册
        if(loginUser == null){
            loginUser = new User();

            loginUser.setMobile(phone);
            // 将手机号截取并md5加密
            String phoneStr = phone.substring(5);
            loginUser.setPassword(SecureUtil.md5(phoneStr));

            Long userId = userApi.add(loginUser);
            loginUser.setId(userId);
            // 新用户
            isNew = true;

            // 创建环信用户信息
            String username = Constants.HX_USER_PREFIX + userId;
            String password = Constants.INIT_PASSWORD;
            Boolean isCreate = huanXinTemplate.createUser(username, password);

            if(isCreate){
                // 更新用户表中的环信信息
                User huanxinUser = new User();
                huanxinUser.setId(userId);
                huanxinUser.setHxUser(username);
                huanxinUser.setHxPassword(password);
                userApi.update(huanxinUser);
            }

        }

        // 6、jwtUtils生成token
        String token = JwtUtils.createToken(loginUser.getId(), phone);

        // 7、将token作为key  user对象(转成字符串)作为值存入redis，有效期3天
        String tokenKey = "TOKEN_" + token;
        String loginUserJson = JSON.toJSONString(loginUser);
        redisTemplate.opsForValue().set(tokenKey,loginUserJson,3,TimeUnit.DAYS);

        // 8、登录成功，构造返回结果Map ==> {"token":"xxx","isNew	":"true|false"}
        Map map = new HashMap();
        // 随意返回一个用户id
        map.put("token",token); // A.B.C
        map.put("isNew",isNew);

        return map;

    }

}
